<?php
/**
 * sfActionsFnde extends sfActions and implements methods to filter
 * and pagination.
 *
 */
class sfActionsFoxsis extends sfActions
{

    const MSG_FILTRAGEM_EFETUADA  = 'Filtragem Efetuada.';
    const FILTER_INSTANCE_NAME = 'filter';
    const FILTER_HTML_KEY = 'filter';
    const FILTER_SESSION_USER_ATTRIBUTE = 'filter';

    const FILTER_SUCCESS = 1;
    const FILTER_ERROR =   2;

    ### UTIL

    public function getRequestParameter($name, $default = null)
    {
        if(is_array($name)) {
            $valor = $this->requestParameterHolder->get($name[0]);
            if(isset($valor[$name[1]])) {
                return $valor[$name[1]];
            }
            else {
                return $default;
            }
        }
        else {
            return $this->requestParameterHolder->get($name, $default);
        }
    }

    public function erroGenerico() {
        print_r($this->getRequest()->getErrors());
        die();
    }
    ### FILTROS E PAGINA��O

    /**
     * Set the actual page in the session if this is not setted
     *
     * @return actual page
     */
    protected function _setActualPage() {
        $ns = $this->getModuleName();
        if($this->hasRequestParameter('pg_num')) {
            $paginaAtual = $this->getRequestParameter('pg_num');
        }
        else {
            $paginaAtual =
            $this->getUser()->getAttribute('pg_num',1,$ns);
        }
        $this->getUser()->setAttribute('pg_num',$paginaAtual,$ns);
        return $paginaAtual;
    }

    /**
     * Get the filter from or create a new in the session
     *
     * @param array $defaultValues
     * @return filter
     */

    protected function _getFilter($defaultValues = array()) {
        $ns = $this->getModuleName();
        if($this->getUser()->hasAttribute(self::FILTER_SESSION_USER_ATTRIBUTE,$ns)) {
            $filter = unserialize(
            $this->getUser()->getAttribute(self::FILTER_SESSION_USER_ATTRIBUTE,null,$ns)
            );
        }
        else {
            $filter = new Filtro(
            array(),
            $defaultValues
            );
            $filter->setCulture($this->getUser()->getCulture());
        }
        return $filter;
    }

    public function executeFilter() {
        $ns = $this->getModuleName();
        $filter = new Filtro(
        $this->getRequestParameter(self::FILTER_SESSION_USER_ATTRIBUTE)
        );
        $filter->setCulture($this->getUser()->getCulture());
        $this->getUser()->setAttribute('pg_num',1,$ns);
        $this->setFlash('mensagem',self::MSG_FILTRAGEM_EFETUADA,false);
        $this->getUser()->setAttribute(
        self::FILTER_SESSION_USER_ATTRIBUTE,
        serialize($filter),
        $ns
        );
        return $this->route(self::FILTER_SUCCESS);
    }

    public function handleErrorFilter() {
        return $this->route(self::FILTER_ERROR);
    }

    ### UPLOAD / IMAGENS E CACHE

    protected function receberUpload(
    &$objeto,
    $campo,
    $nome_parametro,
    $obrigatorio = false,
    $caminho = ''
    ) {
        if ($this->getRequest()->hasFile($nome_parametro))
        {
            $sucesso = true;
            $nome_arquivo  = $this->getRequest()->getFileName($nome_parametro);
            //$fileSize  = $this->getRequest()->getFileSize($fileName);
            //$fileType  = $this->getRequest()->getFileType($fileName);
            $uploadDir = sfConfig::get('sf_upload_dir');
            $this->getRequest()->moveFile($nome_parametro, $uploadDir.DIRECTORY_SEPARATOR.$caminho.$nome_arquivo);
            if($this->getRequest()->hasFileError($nome_parametro)) {
                $codErro = $this->getRequest()->getFileError($nome_parametro);
                if(
                $obrigatorio || $codErro != 4
                ) {
                    switch($codErro) {
                        case 1:
                            $msg = 'Arquivo maior do que a configuração do servidor.';
                            break;
                        case 2:
                            $msg = 'Arquivo maior do que a configuração do formul�rio.';
                            break;
                        case 3:
                            $msg = 'Upload incompleto.';
                            break;
                        case 4:
                            $msg = 'Arquivo obrigatório';
                            break;
                    }
                    $this->getRequest()->setError(
                    $nome_parametro,
                    $msg
                    );
                    $sucesso = false;
                }
            }
            else {
                $objeto->set($campo, $nome_arquivo);
            }
            return $sucesso;
        }
        else {
            if($this->getRequest()->isXmlHttpRequest()) {
                $mensagem = 'Uploads não funcionam com HttpRequest';
            }
            else {
                $mensagem = 'O campo de upload não foi enviado.';
            }
            $this->getRequest()->setError(
            $nome_parametro,
            $mensagem
            );
            return false;
        }
        return false;
    }

    protected function verifyUpload(
    $parameterName,
    $required = false
    ) {
        $msg = null;
        if ($this->getRequest()->hasFile($parameterName))
        {
            $sucesso = true;
            $nome_arquivo  = $this->getRequest()->getFileName($parameterName);
            if($this->getRequest()->hasFileError($parameterName)) {
                $codErro = $this->getRequest()->getFileError($parameterName);
                if(
                $required || $codErro != 4
                ) {
                    switch($codErro) {
                        case 1:
                            $msg = 'Arquivo maior do que a configuração do servidor.';
                            break;
                        case 2:
                            $msg = 'Arquivo maior do que a configuração do formulário.';
                            break;
                        case 3:
                            $msg = 'Upload incompleto.';
                            break;
                        case 4:
                            $msg = 'Arquivo obrigatório';
                            break;
                    }
                    $sucesso = false;
                }
            }
        }
        else {
            if($this->getRequest()->isXmlHttpRequest()) {
                $msg = 'Uploads não funcionam com HttpRequest';
            }
            else {
                $msg = 'O campo de upload não foi enviado.';
            }
            $sucesso = false;
        }
        $tmp_file = $this->getRequest()->getFileValue($parameterName, 'tmp_name');
        if($tmp_file !== '') { // string(0) neste framework quer dizer que o usuário quer remover a imagem
            if(!is_uploaded_file($tmp_file)) {
                $msg = 'O arquivo não é um upload válido.';
                $sucesso = false;
            }
        }
        if($msg) {
            $this->getRequest()->setError(
            $parameterName,
            $msg
            );
        }
        return $sucesso;
    }

    protected function clearCache($pkValue,$className,$fieldName) {
        $caminho = $this->cacheDir($className,$fieldName).$pkValue;
        $caminhos = glob($caminho.'_thumb*');
        $caminhos[] = $caminho;
        foreach($caminhos as $caminho) {
            if(file_exists($caminho)) {
                if(!is_writeable($caminho)) {
                    throw new Exception('O sistema está sem permissão para limpar o arquivo de cache.');
                }
                unlink($caminho);
            }
        }
    }

    protected function cacheDir($className,$fieldName) {
        return
        sfConfig::get('sf_cache_dir')
        .DIRECTORY_SEPARATOR
        .strtolower($className).'_'.$fieldName
        .DIRECTORY_SEPARATOR;
    }

    protected function showImage(
    $pkValue,
    $className,
    $fieldName,
    $msgNoImage,
    $resizeValues = null
    ) {
        if($resizeValues !== null) {
            if(is_array($resizeValues) && count($resizeValues) == 2) {
                $width = $resizeValues[0];
                $height = $resizeValues[1];
                $generateThumb = true;
            }
            else {
                trigger_error('O parâmetro resizeValues deve ser um array com [width,heigth]');
            }
        }
        else {
            $generateThumb = false;
        }
        sfConfig::set('sf_web_debug', false);
        $dir = $this->cacheDir($className,$fieldName);
        if($generateThumb) {
            $caminhoThumb = $dir.$pkValue.'_thumb_'.$width.'_'.$height;
            $caminhoOriginal = $dir.$pkValue;
        }
        $caminhoOriginal = $dir.$pkValue;

        if(!file_exists($dir)) {
            if(!is_writeable($dir)) {
                throw new Exception('O diretório de cache está sem permissão de gravação.');
            }
            mkdir($dir,0777);
        }
        if(!file_exists($caminhoOriginal)) {
            $obj = Doctrine::getTable($className)->find($pkValue);
            $streamOrigem = $obj->get($fieldName);
            if(is_resource($streamOrigem)) {
                $destResource = fopen($caminhoOriginal,'w+');
                fwrite($destResource, stream_get_contents($streamOrigem));
                fclose($destResource);
                $existe = true;
            }
            else {
                $existe = false;
            }
        }
        else {
            $existe = true;
        }
        if($existe && $generateThumb) {
            $thumbnail = new sfThumbnail($width, $height);
            $thumbnail->loadFile($caminhoOriginal);
            $thumbnail->save($caminhoThumb);
        }
        if($existe) {
            header("Content-Type: image");
            if($generateThumb) {
                return $this->renderText(file_get_contents($caminhoThumb));
            }
            else {
                return $this->renderText(file_get_contents($caminhoOriginal));
            }
        }
        else {
            return $this->renderText($msgNoImage);
        }
    }

    ###  HTTP REQUEST


    protected function listaJsonChavesDescricoes($ar_valores) {
        $this->getResponse()->setHttpHeader(
      "Content-type", "application/json"
      );
      $this->getResponse()->setContent(
      '('.
      json_encode(
      array(
            'chaves'=>array_keys($ar_valores),
            'descricoes'=>array_values($ar_valores)
      )
      )
      .')'
      );
      return sfView::NONE;
    }

    protected function atualizarDivComHtml(
    $nome_div = null, // se null aqui, no js deve ser obrigat�rio.
    $html)
    {
        $this->partial = $html;
        $this->header_json($nome_div);
        $this->setTemplate('partial');
        $this->setLayout(false);
    }

    protected function atualizarDivComPartial(
    $nome_div = null, // se null aqui, no js deve ser obrigat�rio.
    $caminho_partial,
    $ar_valores)
    {
        ##precisa renderizar primeiro pois define as mensagens que n�o est�o no form.
        sfLoader::loadHelpers('Partial');
        $this->partial =
        get_partial(
        $caminho_partial,
        $ar_valores
        );
        $this->header_json($nome_div);
        $this->setTemplate('partial');
        $this->setLayout(false);
    }

    protected function atualizarDivComComponent(
    $nome_div = null, // se null aqui, no js deve ser obrigat�rio.
    $moduleName,
    $componentName,
    $values)
    {
        ##precisa renderizar primeiro pois define as mensagens que n�o est�o no form.
        sfLoader::loadHelpers('Partial');
        $this->partial =
        get_component(
        $moduleName,
        $componentName,
        $values
        );
        $this->header_json($nome_div);
        $this->setTemplate('partial');
        $this->setLayout(false);
    }

    protected function header_json($nome_div_atualizar = false) {
        ##monta o cabecalho, indicando as mensagens e o div a atualizar.
        $ar = array();
        $ar['mensagem'] = $this->mensagens_json();
        if($nome_div_atualizar) {
            $ar['div_atualizar']=$nome_div_atualizar;
        }
        $this->getResponse()->setHttpHeader(
      "X-JSON", 
      '('.json_encode($ar).')'
      );
    }

    protected function mensagens_json() {
        ##pega todas as mensagens.
        $errosMostrados = $this->request->getParameterHolder()->get('errosMostrados');
        $mensagem = '';
        foreach($this->request->getErrors() as $campo=>$erro) {
            if(!in_array($campo,$errosMostrados)) {
                $mensagem .=  "Erro não mostrado:".$erro.'.';
            }
        }
        if($this->request->getParameterHolder()->has('errosMostrados')) {
            $mensagem .= 'Por favor corrija os erros indicados.';
        }
        $mensagem .= $this->getFlash('mensagem');
        $mensagem .= $this->getFlash('erro');
        return utf8_encode($mensagem);
    }

    protected function veioPorHttpRequestDe($modulo,$acao) {
        $primeiraAcao = $this->getContext()->getActionStack()->getFirstEntry();
        return
        $this->getRequest()->isXmlHttpRequest() &&
        $primeiraAcao->getActionName() == $acao &&
        $primeiraAcao->getModuleName() == $modulo;
    }

    /**
     * Sets a flash variable that will be passed to the very next action.
     *
     * @param  string  The name of the flash variable
     * @param  string  The value of the flash variable
     * @param  boolean true if the flash have to persist for the following request (true by default)
     */
    public function setFlash($name, $value, $persist = true)
    {
        $this->getUser()->setFlash($name, $value, $persist);
    }

    /**
     * Gets a flash variable.
     *
     * @param  string The name of the flash variable
     *
     * @return mixed The value of the flash variable
     */
    public function getFlash($name)
    {
        return $this->getUser()->getFlash($name);
    }

    /**
     * Returns true if a flash variable of the specified name exists.
     *
     * @param  string The name of the flash variable
     *
     * @return boolean   true if the variable exists, false otherwise
     */
    public function hasFlash($name)
    {
        return $this->getUser()->hasFlash($name);
    }
}
?>